package com.piece.blog.service;

import com.piece.blog.dto.TrainingChaptersDTO;
import com.piece.blog.dto.TrainingCourseDTO;
import com.piece.blog.dto.TrainingHourDTO;
import com.piece.blog.model.CourseChapters;
import com.piece.blog.model.CourseHour;
import com.piece.blog.model.TrainingCourse;
import com.piece.blog.repository.CourseChaptersRepository;
import com.piece.blog.repository.CourseHourRepository;
import com.piece.blog.repository.TrainingCourseRepository;
import com.piece.core.framework.enums.sql.SqlKey;
import com.piece.core.framework.support.bootstrap.Order;
import com.piece.core.framework.support.convert.Convert;
import com.piece.core.framework.util.collection.MapUtil;
import com.piece.core.framework.util.object.BeanUtil;
import com.piece.core.framework.util.string.StringUtil;
import com.piece.core.jpa.repository.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
public class TrainingCourseService extends BaseService<TrainingCourse, String> {

    @Autowired
    private TrainingCourseRepository trainingCourseRepository;

    @Autowired
    private CourseChaptersRepository courseChaptersRepository;

    @Autowired
    private CourseHourRepository courseHourRepository;

    @PostConstruct
    public void initRepository() {
        setRepository(trainingCourseRepository);
    }

    public TrainingCourseDTO queryCourseInfo(Long courseId) {
        TrainingCourse trainingCourse = findById(courseId);
        if (null != trainingCourse) {
            TrainingCourseDTO course = new TrainingCourseDTO();
            List<CourseChapters> chapters = courseChaptersRepository.findByCondition(MapUtil.builder(new HashMap<String, Object>())
                    .put("courseId", trainingCourse.getCourseId()).build(), Arrays.asList(new Order("sort", SqlKey.ASC)));
            List<CourseHour> hours = courseHourRepository.findByCondition(MapUtil.builder(new HashMap<String, Object>())
                    .put("courseId", trainingCourse.getCourseId()).build(), null);
            List<TrainingChaptersDTO> chapterList = chapters.stream().map(chapter -> {
                TrainingChaptersDTO dto = new TrainingChaptersDTO();
                BeanUtil.copyProperties(chapter, dto);
                dto.setChapterId(chapter.getChapterId());
                dto.setCourseId(trainingCourse.getCourseId());
                dto.setHours(searchChapterHours(chapter.getChapterId(), hours));
                return dto;
            }).collect(Collectors.toList());

            course.setCourseId(trainingCourse.getCourseId());
            course.setCourseName(trainingCourse.getCourseName());
            course.setChapters(chapterList);
            return course;
        }

        return new TrainingCourseDTO();
    }

    private List<TrainingHourDTO> searchChapterHours(Long chapterId, List<CourseHour> hours) {
        return hours.stream().filter(hour -> hour.getChapterId() == chapterId).map(hour -> {
            TrainingHourDTO dto = new TrainingHourDTO();
            BeanUtil.copyProperties(hour, dto);
            dto.setHourId(hour.getHourId());
            dto.setCourseId(hour.getCourseId());
            dto.setChapterId(hour.getChapterId());
            dto.setResourceId(hour.getResourceId());
            return dto;
        }).sorted(Comparator.comparing(TrainingHourDTO::getSort)).collect(Collectors.toList());
    }

    public void saveCourseHour(TrainingCourseDTO trainingCourse) {
        // 清空历史数据
        Long courseId = Convert.toLong(trainingCourse.getCourseId());
        clearCourseInfo(courseId);

        long index = 1;
        List<CourseHour> courseHours = new ArrayList<>();
        List<TrainingChaptersDTO> chapters = trainingCourse.getChapters();
        for (TrainingChaptersDTO chapter: chapters) {
            if (StringUtil.isNotEmpty(chapter.getChapterName())) {
                CourseChapters courseChapter = new CourseChapters();
                courseChapter.setCourseId(courseId);
                courseChapter.setChapterName(chapter.getChapterName());
                courseChapter.setSort(index++);
                courseChapter = courseChaptersRepository.insert(courseChapter);

                List<TrainingHourDTO> hours = chapter.getHours();
                long index_ = 1;
                for (TrainingHourDTO hour: hours) {
                    if (null != hour.getResourceId()) {
                        CourseHour courseHour = new CourseHour();
                        courseHour.setCourseId(courseId);
                        courseHour.setChapterId(courseChapter.getChapterId());
                        courseHour.setResourceId(Convert.toLong(hour.getResourceId()));
                        courseHour.setType(hour.getType());
                        courseHour.setTitle(hour.getTitle());
                        courseHour.setDuration(hour.getDuration());
                        courseHour.setSort(index_++);
                        courseHours.add(courseHour);
                    }
                }
            }
        }

        if (courseHours.size() > 0) {
            courseHourRepository.batchInsert(courseHours);
            // 设置课程课时数
            trainingCourseRepository.executeSql("update training_course set class_hour =?0 where course_id =?1", new Object[]{ courseHours.size(), courseId });
        }
    }

    private void clearCourseInfo(Long courseId) {
        courseChaptersRepository.deleteByProperties("courseId", courseId);
        courseHourRepository.deleteByProperties("courseId", courseId);
    }
}
